package cn.qy.kotlin.base.ch11

/**
 * PlayerCh11 用于 ch11 章节
 */
class Player(
    _name: String = "Madrigal",
    var healthPoints: Int = 100,
    val isBlessed: Boolean,
    private val isImmortal: Boolean
) {
    // 默认情况下，属性的 getter 和 setter 方法的可见性与属性一致。所以，如果属性是 public，那么它的 getter 和 setter 方法也 是 public 的。
    var name = _name
        // field 用来存储属性数据。你不能直接定义 field，Kotlin 会封装 field，保护它里面的数据
        // 某个属性的 getter 和 setter 方法的可见性不能比该属性自身的可见性更宽松。你可以通过 getter 或 setter 方法来限制属性的访问，但它们不是用来让属性更加暴露的。
        get() {
            return field.capitalize()
        }
        // 只有可变属性才会有 setter 方法
        set(value) {
            field = value.trim()
        }

    lateinit var alignment: String

    // 给类定义一个初始化块。设置变量或值，以及执行有效性检查，如检查传给某构造函数的值是否有效
    init {
        require(healthPoints > 0, { "healthPoints must be greater than zero." })
        require(name.isNotBlank(), { "Player must have a name." })
    }

    constructor(name: String) : this(name, healthPoints = 100, isBlessed = true, isImmortal = false) {
        if (name.toLowerCase() == "kar") healthPoints = 40
    }

    fun auraColor(): String {
        val auraVisible = isBlessed && healthPoints > 50 || isImmortal
        return if (auraVisible) "GREEN" else "NONE"
    }

    fun proclaimFate() {
        // 用到的 isInitialized 检查。 为避免触发 UninitializedPropertyAccessException 异常
        if (::alignment.isInitialized) println(alignment)
    }

    fun formatHealthStatus() =
        when (healthPoints) {
            100 -> "is in excellent condition!"
            in 90..99 -> "has a few scratches."
            in 75..89 -> if (isBlessed) {
                "has some minor wounds, but is healing quite quickly!"
            } else {
                "has some minor wounds."
            }
            in 15..74 -> "looks pretty hurt."
            else -> "is in awful condition!"
        }

    fun castFireball(numFireballs: Int = 2) = println("A glass of Fireball springs into existence. (x$numFireballs)")
}